#pragma once

#include "../base/types.h"
#include <stdlib.h>

OPEN_JLIB_NS


struct Vec2i {

  s32 p[2];

  inline Vec2i () noexcept {
  }
  inline Vec2i (s32 x, s32 y) noexcept {
    p[0] = x;
    p[1] = y;
  }
  inline Vec2i (s32 s) noexcept {
    p[0] = s;
    p[1] = s;
  }
  inline Vec2i (const s32* m) noexcept {
    p[0] = m[0];
    p[1] = m[1];
  }


  inline s32 x () const noexcept {
    return p[0];
  }
  inline s32 y () const noexcept {
    return p[1];
  }


  inline Vec2i& x (s32 s) noexcept {
    p[0] = s;
    return *this;
  }
  inline Vec2i& y (s32 s) noexcept {
    p[1] = s;
    return *this;
  }


  inline bool operator== (Vec2i v) const noexcept {
    return p[0] == v.p[0] && p[1] == v.p[1];
  }
  inline bool operator!= (Vec2i v) const noexcept {
    return p[0] != v.p[0] || p[1] != v.p[1];
  }


  inline Vec2i& operator+= (Vec2i v) noexcept {
    p[0] += v.p[0];
    p[1] += v.p[1];
    return *this;
  }
  inline Vec2i& operator-= (Vec2i v) noexcept {
    p[0] -= v.p[0];
    p[1] -= v.p[1];
    return *this;
  }
  inline Vec2i& operator*= (Vec2i v) noexcept {
    p[0] *= v.p[0];
    p[1] *= v.p[1];
    return *this;
  }
  inline Vec2i& operator/= (Vec2i v) noexcept {
    p[0] /= v.p[0];
    p[1] /= v.p[1];
    return *this;
  }
  inline Vec2i& operator%= (Vec2i v) noexcept {
    p[0] %= v.p[0];
    p[1] %= v.p[1];
    return *this;
  }


  inline Vec2i& operator*= (s32 s) noexcept {
    p[0] *= s;
    p[1] *= s;
    return *this;
  }
  inline Vec2i& operator/= (s32 s) noexcept {
    p[0] /= s;
    p[1] /= s;
    return *this;
  }
  inline Vec2i& operator%= (s32 s) noexcept {
    p[0] %= s;
    p[1] %= s;
    return *this;
  }


  inline Vec2i operator+ (Vec2i v) const noexcept {
    return {p[0]+v.p[0], p[1]+v.p[1]};
  }
  inline Vec2i operator- (Vec2i v) const noexcept {
    return {p[0]-v.p[0], p[1]-v.p[1]};
  }
  inline Vec2i operator* (Vec2i v) const noexcept {
    return {p[0]*v.p[0], p[1]*v.p[1]};
  }
  inline Vec2i operator/ (Vec2i v) const noexcept {
    return {p[0]/v.p[0], p[1]/v.p[1]};
  }
  inline Vec2i operator% (Vec2i v) const noexcept {
    return {p[0]%v.p[0], p[1]%v.p[1]};
  }


  inline Vec2i operator* (s32 s) const noexcept {
    return {p[0]*s, p[1]*s};
  }
  inline Vec2i operator/ (s32 s) const noexcept {
    return {p[0]/s, p[1]/s};
  }
  inline Vec2i operator% (s32 s) const noexcept {
    return {p[0]%s, p[1]%s};
  }


  inline Vec2i operator+ () const noexcept {
    return {abs(p[0]), abs(p[1])};
  }
  inline Vec2i operator- () const noexcept {
    return {-p[0], -p[1]};
  }
};


inline Vec2i operator* (s32 a, Vec2i b) noexcept {
  return b * a;
}


CLOSE_JLIB_NS